using System;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;


namespace _1945
{
    public class GameObject : DrawableGameComponent
    {

        #region Variables
        protected Texture2D gameSpriteSheet;
        protected SpriteBatch spriteBatch;
        protected SpriteFont spriteFont;
        protected SpriteFactory spriteFactory;

        protected int scale;
        protected Vector2 position;
        protected Vector2 startPos;
        protected Vector2 drawPosition; //rounded position
        public Vector2 Position { get { return position; } }
        protected int score;
        protected Vector2 speed;
        protected Vector2 direction;
        protected Sprite sprite; //sprite used by the gameobject
        
        protected Rectangle boundingRectangle = new Rectangle(); //collision detection. 
        public Rectangle BoundingRectangle { get { return boundingRectangle; } }
        protected Rectangle gameScreenBounds;
        
        protected bool hasExploded = false;
        public bool HasExploded { get { return hasExploded; } }
        protected bool isExploding = false;
        public bool IsExploding { get { return isExploding; } }
        
        public int Width { get { return sprite.getWidth(); } }
        public int Height { get { return sprite.getHeight(); } }

        private bool drawBoundingBox = false; //set to true to draw a black box around every gameobject
        protected Texture2D blackTexture;
        
        #endregion

        #region Constructors
        /// <summary>
        /// 
        /// </summary>
        /// <param name="game">Gameobject</param>
        /// <param name="gameSpriteSheet">Spritesheet</param>
        /// <param name="startpos">Where sprites initial position is on screen.</param>
        /// <param name="speed">At which speed sprite moves</param>
        /// <param name="direction">Where the sprite is heading</param>
        /// <param name="sprite">The sprite gotten from the SpriteFactory</param>
        /// <param name="gameScreenBounds">Recatangle of the game screen window</param>
        public GameObject(Game game, Texture2D gameSpriteSheet, Vector2 startpos, Vector2 speed, Vector2 direction, Sprite sprite, Rectangle gameScreenBounds)
            : base(game)
        {
            this.spriteBatch = (SpriteBatch)Game.Services.GetService(typeof(SpriteBatch));
            spriteFont = (SpriteFont)Game.Services.GetService(typeof(SpriteFont));
            spriteFactory = (SpriteFactory)Game.Services.GetService(typeof(SpriteFactory));
            this.gameSpriteSheet = gameSpriteSheet;
            this.startPos = startpos;
            this.position = startpos;
            this.speed = speed;
            this.direction = direction;
            this.sprite = sprite;
            this.gameScreenBounds = gameScreenBounds;
            setCollisionBox();

            createTexture();
        }
        #endregion

        private void createTexture(){
            //used for drawing a box around every sprite
            //also used as health bar
            blackTexture = new Texture2D(Game.GraphicsDevice, 2, 2, 0, TextureUsage.None, SurfaceFormat.Color);
            Color[] pixels;
            pixels = new Color[4];
            for (int i = 0; i < pixels.Length; i++)
                pixels[i] = Color.White;
            blackTexture.SetData(pixels);
        }

        private void setCollisionBox()
        {
            boundingRectangle.X = (int)position.X;
            boundingRectangle.Y = (int)position.Y;
            boundingRectangle.Width = sprite.getWidth();
            boundingRectangle.Height = sprite.getHeight();
        }

        public Boolean checkCollision(Rectangle gameObjectBoundingRectangle)
        {
            if (this.boundingRectangle.Intersects(gameObjectBoundingRectangle))
                return true;
            else
                return false;
        }

        public void explode(GameTime gameTime)
        {
            isExploding = true;
            direction = new Vector2(0);
            sprite = spriteFactory.getExplosionSprite(SpriteFactory.explosions.small, gameTime.TotalGameTime);
            setCollisionBox();
         }

        public bool isOffScreen()
        {
            if (position.X + Width < 0 || position.X > gameScreenBounds.Width || position.Y + Height + 10 < 0 || position.Y > gameScreenBounds.Height)
            {
                return true;
            }
            return false;
        }

        public override void Update(GameTime gameTime)
        {
            
            if (!IsExploding)
            {
                position.X += direction.X * speed.X;
                position.Y += direction.Y * speed.Y;
            }

            if (sprite.getIsAnimated())
            {
                if (isExploding && sprite.getIsAnimationFinished(gameTime.TotalGameTime))
                {
                    hasExploded = true;
                }

                sprite.nextAnimatedFrame(gameTime.TotalGameTime);
            }

            setCollisionBox(); //Collision detection
        }//end update

        public override void Draw(GameTime gameTime)
        {
            if (drawBoundingBox)
            {
                spriteBatch.Draw(blackTexture, boundingRectangle, Color.White);
            }

            drawPosition.X = (float)Math.Round(position.X);
            drawPosition.Y = (float)Math.Round(position.Y);
            spriteBatch.Draw(gameSpriteSheet, drawPosition, sprite.getSpriteRectangle(), Color.White);
        }

    }
}